package com.evildog.workspace.file.upload.uploader;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.evildog.workspace.common.exception.ServerErrorException;
import com.evildog.workspace.common.util.WsAssert;
import com.evildog.workspace.file.enums.DocStorageTypeEnum;
import com.evildog.workspace.file.enums.FileCustomExceptionDesc;
import com.evildog.workspace.file.upload.object.VirtualFileDTO;
import com.evildog.workspace.file.upload.properties.FileNginxProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

@Slf4j
@RequiredArgsConstructor
public class LocalFileUploader extends AbstractFileUploader implements FileUploader {

    private final FileNginxProperties fileNginxProperties;

    private String prefix;

    private String serverPath;

    @PostConstruct
    public void init() {
        this.prefix = fileNginxProperties.getPrefix().endsWith(File.separator)
                ?  fileNginxProperties.getPrefix() :  fileNginxProperties.getPrefix() + File.separator;
        this.serverPath = fileNginxProperties.getServerPath().endsWith(File.separator)
                ? fileNginxProperties.getServerPath() : fileNginxProperties.getServerPath() + File.separator;
    }

    @Override
    public VirtualFileDTO upload(InputStream inputStream, String originalName, String folder) {
        WsAssert.hasText(folder, FileCustomExceptionDesc.FOLDER_NOT_HAS_TEXT);

        String newFilename = this.createNewFilename(originalName);

        String relativeUrl = folder + File.separator + newFilename;

        // 文件保存的正式路径
        String saveFilePath = serverPath + relativeUrl;
        FileUtil.mkParentDirs(saveFilePath);

        try (InputStream newInputStream = inputStream;
             FileOutputStream fos = new FileOutputStream(saveFilePath)) {
            IoUtil.copy(newInputStream, fos);

            return new VirtualFileDTO()
                    .setSize(inputStream.available())
                    .setAbsoluteUrl(this.prefix + relativeUrl)
                    .setRelativeUrl(relativeUrl)
                    .setFilename(originalName)
                    .setStorageType(DocStorageTypeEnum.LOCAL_FILE.getValue())
                    .setSuffix(FileUtil.getSuffix(originalName));

        } catch (IOException e) {
            log.error("上传失败", e);
            throw new ServerErrorException(FileCustomExceptionDesc.INPUT_STREAM_UPLOAD_FAILED);
        }
    }

    @Override
    public boolean remove(String relativePath) {
        WsAssert.hasText(relativePath, FileCustomExceptionDesc.RELATIVE_PATH_NOT_HAS_TEXT);
        return FileUtil.del(this.serverPath + relativePath);
    }
}
